package com.touch.core.plugin;
import java.io.File;
import java.util.*;

import com.touch.core.resources.ClassManager;
import com.touch.core.util.IOTools;
public class PluginManager extends ClassManager 
{
	/**
	 * Loads a plugin from the local database
	 * @param name Name of the Class
	 * @param path Absolute path of the class
	 * @return
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	@SuppressWarnings("unchecked")
	public IPlugin loadPlugin(final String name, final String path) throws ClassNotFoundException
	{		
		//create a new Class object from the class file
		Class plugin = super.loadClass(name, path, true);		
		try
		{			
			//attempt to cast the object as an IPlugin
			IPlugin ret = (IPlugin)plugin.newInstance();
			//run the "load" method from the plugin.
			ret.load();
			//return the plugin
			return ret;
		}
		catch(final Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}
	@SuppressWarnings("unchecked")
	public IPlugin loadPluginFromJar(final String name, final String archive)throws ClassNotFoundException
	{
		//create a Class object from the class file
		Class plugin	= super.loadClassFromJar(name, archive, true);
		try
		{
			//Attempt to cast the object to IPlugin
			IPlugin ret		= (IPlugin)plugin.newInstance();
			//load the plugin
			ret.load();		
			//return the plugin
			return ret;
		}
		catch(Exception e)
		{
			return null;
		}
	}
	@SuppressWarnings("unchecked")
	/**
	 * Loads a whole package when given a String
	 */
	public HashMap<String, IPlugin> loadPackage(final String archive) throws ClassNotFoundException
	{
		//list of classes
		final Vector <Class> classes = super.loadPackage(archive, true);
		final HashMap <String, IPlugin> plugins = new HashMap<String, IPlugin>();
		//scroll through the list of classes
		for(int i = 0; i < classes.size(); i++)
		{
			try
			{
				//create a new plugin, cast to IPlugin
				IPlugin plugin = (IPlugin)classes.elementAt(i).newInstance();
				//load the plugin
				plugin.load();
				plugins.put(plugin.getClass().getSimpleName(), plugin);			
			}	
			catch(final Exception e){}
		}
		return plugins;
	}
	/**
	 * Creates the plugin using the default constructor. This requires the plugin to be loaded first.
	 * @param name Name of the plugin
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public IPlugin newPlugin(final String name) throws InstantiationException, IllegalAccessException
	{		
		//just create a new object and cast to IPlugin for returning it.
		return (IPlugin)super.checkTable(name).newInstance();	
	}		
	/**
	 * Load the package from a list of given strings
	 * @param paths
	 */
	public void loadPackages(final String ... paths)
	{		
		//Enumerate through the list of Strings
		for(String path: paths)
		{
			//get all the files from the file
			final File[] files = IOTools.getFiles(path);
			//Enumerate through the list of files
			for(File file: files)
			{
				//Check to confirm that the file is a zip archive
				if(file.getName().endsWith(".jar") || file.getName().endsWith(".zip"))
				{
					//attempt to load the package
					try
					{
						this.loadPackage(path + "/" + file.getName());
					}
					catch(final Exception e)
					{
						e.printStackTrace();
					}
				}
			}
		}
	}
}
